package com.mxr.boot;

import java.beans.PropertyVetoException;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.mchange.v2.c3p0.ComboPooledDataSource;

@Configuration
@ComponentScan(basePackages = {"com.mxr"}, excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class, RestController.class})} )
@MapperScan(basePackages = {"com.mxr.dao"})//扫描指定包下的Mapper接口，并找到对应同名的MapperSql映射文件，将两者绑定
@PropertySource(value = {"classpath:jdbc.properties"})
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)//使Spring注解驱动的事务管理能力，类似于Spring的 XML 命名空间中的支持。用于@Configuration类，如下所示︰<tx:*>
@EnableAspectJAutoProxy//启用对处理组件使用AspectJ的注释，类似于在Spring的 XML元素中找到的功能标记的支持。
public class AppConfig {

	@Autowired
	private Environment env;
	
	/**
	 * 配置C3P0数据源
	 * @return
	 * @throws PropertyVetoException
	 */
	@Bean(destroyMethod = "close")
	public DataSource dataSource () {
		
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		try {
			dataSource.setDriverClass(env.getProperty("driverClass"));
		} catch (PropertyVetoException e) {
			throw new RuntimeException("DriverClass属性的值不正确！", e);
		}
		dataSource.setJdbcUrl(env.getProperty("jdbcUrl"));
		dataSource.setUser(env.getProperty("user"));
		dataSource.setPassword(env.getProperty("password"));
		
		return dataSource;
	}
	
	/**
	 * 配置SqlSessionFactoryBean
	 * @return
	 * @throws Exception 
	 */
	@Bean(autowire = Autowire.BY_NAME)
	public SqlSessionFactory sqlSessionFactoryBean () throws Exception {
		MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource());
		sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
		sqlSessionFactoryBean.setTypeAliasesPackage("com.mxr.model");
		
		//全局配置
		GlobalConfiguration globalConfig = new GlobalConfiguration();
		globalConfig.setDbType(DbType.ORACLE.name());
		//ID 策略 AUTO->`0`("数据库ID自增") INPUT->`1`(用户输入ID") ID_WORKER->`2`("全局唯一ID") UUID->`3`("全局唯一ID")
		globalConfig.setIdType(3);
		sqlSessionFactoryBean.setGlobalConfig(globalConfig);
		
		return sqlSessionFactoryBean.getObject();
	}
	
	/**
	 * 配置Mybatis事务管理器
	 * @return
	 * @throws PropertyVetoException
	 */
	@Bean(autowire = Autowire.BY_NAME)
	public PlatformTransactionManager transactionManager () throws PropertyVetoException {
		return new DataSourceTransactionManager(dataSource());
	}
}
